/*
* 文件：ConsoleUI.cs
* 作者：王阳
* 时间：2019-5-20
* 描述：Unity控制台UI
*/

using CSharpX;
using System;
using System.Collections.Generic;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace UnityX
{
    /// <summary>
    /// Unity控制台UI
    /// </summary>
    internal class ConsoleUI
    {
        private class ConsoleCanvas : UnityEngine.MonoBehaviour
        {
            public ConsoleUI consoleUI;
            public void Update()
            {
                consoleUI.Update();
            }
            public void OnRectTransformDimensionsChange()
            {
                consoleUI.RefreshWindowSize();
            }
        }
        private class ConsoleWindow : UnityEngine.MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
        {
            private UnityEngine.Vector3 offsetPos;
            private bool isPointer = false;
            private UnityEngine.RectTransform rectTransform;
            public void Start()
            {
                rectTransform = GetComponent<UnityEngine.RectTransform>();
            }
            public void OnPointerDown(PointerEventData eventData)
            {
                isPointer = true;
                offsetPos = rectTransform.position - UnityEngine.Input.mousePosition;
            }
            public void OnPointerUp(PointerEventData eventData)
            {
                isPointer = false;
            }
            public void OnDrag(PointerEventData eventData)
            {
                if (isPointer)
                {
                    rectTransform.position = new UnityEngine.Vector3(
                        UnityEngine.Mathf.Clamp(UnityEngine.Input.mousePosition.x, 10, UnityEngine.Screen.width - 10),
                        UnityEngine.Mathf.Clamp(UnityEngine.Input.mousePosition.y, 10, UnityEngine.Screen.height - 10),
                        0) + offsetPos;
                }
            }
        }
        private class ItemData
        {
            public string content;
            public string stack;
            public DateTime time;
            public UnityEngine.LogType type;
            public UnityEngine.GameObject gameObject;
        }

        private UnityEngine.Color m_InfoColor = new UnityEngine.Color(1, 1, 1, 1);
        private UnityEngine.Color m_WarningColor = new UnityEngine.Color(1, 1, 0.2f, 1);
        private UnityEngine.Color m_ErrorColor = new UnityEngine.Color(1, 0.25f, 0.25f, 1);
        private UnityEngine.Color m_EventColor = new UnityEngine.Color(0.2f, 1, 0.2f, 1);
        private UnityEngine.Color m_WindowBackgroundColor = new UnityEngine.Color(0, 0.2f, 0.2f, 0.9f);
        private UnityEngine.Color m_SeparateLineColor = new UnityEngine.Color(0.5f, 0.5f, 0.5f, 1);

        private int m_MaxCount = 1000;
        private List<ItemData> m_BufferItems = new List<ItemData>();
        private List<ItemData> m_ShowItems = new List<ItemData>();

        private int m_WindowsWidth = 1200;
        private int m_WindowsHeight = 800;
        private int m_FontSize = 16;

        private UnityEngine.GameObject m_CanvasObject;
        private UnityEngine.GameObject m_WindowObject;
        private UnityEngine.GameObject m_TopBar;
        private UnityEngine.GameObject m_LogBar;
        private UnityEngine.GameObject m_InputBar;
        private UnityEngine.GameObject m_LogContent;
        private Dictionary<string, UnityEngine.GameObject> m_UIGameObjects = new Dictionary<string, UnityEngine.GameObject>();

        private bool m_OpenInfo = true;
        private bool m_OpenWarning = true;
        private bool m_OpenError = true;
        private bool m_OpenEvent = true;
        private RawImage m_InfoButtonImage;
        private RawImage m_WarningButtonImage;
        private RawImage m_ErrorButtonImage;
        private RawImage m_EventButtonImage;
        private Text m_InfoButtonText;
        private Text m_WarningButtonText;
        private Text m_ErrorButtonText;
        private Text m_EventButtonText;
        private int m_InfoCount = 0;
        private int m_WarningCount = 0;
        private int m_ErrorCount = 0;
        private int m_EventCount = 0;

        private bool isPause = false;
        private RawImage PauseButtonImage;
        private bool isShowStack = false;
        private RawImage StackButtonImage;

        private ScrollRect m_LogScrollRect;

        private InputField m_LogInputField;
        private string m_LastInputText = "";
        private UnityEngine.Font m_Font = null;

        /// <summary>
        /// 输入消息
        /// </summary>
        public Action<string> OnInput { get; set; }
        /// <summary>
        /// 界面是否打开
        /// </summary>
        public bool isOpen { get { return m_CanvasObject != null && m_CanvasObject.activeSelf; } }
        /// <summary>
        /// 创建控制台界面
        /// </summary>
        /// <param name="maxCount">最大显示数量</param>
        public ConsoleUI(int maxCount)
        {
            this.m_MaxCount = maxCount;
        }
        private void CreateWindow()
        {
            if (m_CanvasObject != null)
            {
                return;
            }

            if (m_Font == null)
            {
#if UNITY_2022_3_OR_NEWER
                m_Font = UnityEngine.Resources.GetBuiltinResource<UnityEngine.Font>("LegacyRuntime.ttf");
#else
                m_Font = UnityEngine.Resources.GetBuiltinResource<UnityEngine.Font>("Arial.ttf");
#endif
            }
            m_FontSize = 16 + (int)Curve.L1(0, 16, 100, 500, UnityEngine.Screen.dpi) + (int)Curve.L1(0, 24, 1000, 5000, UnityEngine.Screen.width < UnityEngine.Screen.height ? UnityEngine.Screen.width : UnityEngine.Screen.height);
            m_FontSize = m_FontSize & 0xFFFE;

            //检测程序是否添加事件系统
            if (EventSystem.current == null)
            {
                UnityEngine.GameObject es = new UnityEngine.GameObject("EventSystem");
                es.AddComponent<EventSystem>();
                es.AddComponent<StandaloneInputModule>();
            }

            //创建界面
            m_CanvasObject = new UnityEngine.GameObject("_ConsoleUI_");
            UnityEngine.Object.DontDestroyOnLoad(m_CanvasObject);
            m_CanvasObject.hideFlags = UnityEngine.HideFlags.HideInHierarchy;
            UnityEngine.Canvas canvas = m_CanvasObject.AddComponent<UnityEngine.Canvas>();
            canvas.renderMode = UnityEngine.RenderMode.ScreenSpaceOverlay;
            canvas.sortingOrder = 32763;
            m_CanvasObject.AddComponent<GraphicRaycaster>();
            m_CanvasObject.AddComponent<ConsoleCanvas>().consoleUI = this;

            m_WindowObject = new UnityEngine.GameObject("_ConsoleWindows_");
            m_WindowObject.transform.SetParent(m_CanvasObject.transform, false);
            m_WindowObject.AddComponent<UnityEngine.CanvasRenderer>();
            RawImage image = m_WindowObject.AddComponent<RawImage>();
            image.color = m_WindowBackgroundColor;
            m_WindowObject.AddComponent<ConsoleWindow>();

            UnityEngine.RectTransform rectTransform;
            Text text;
            //上方按钮部分
            {
                m_TopBar = new UnityEngine.GameObject("_TopBar_");
                m_TopBar.transform.SetParent(m_WindowObject.transform, false);
                m_TopBar.AddComponent<UnityEngine.CanvasRenderer>();
                image = m_TopBar.AddComponent<RawImage>();
                image.color = new UnityEngine.Color(0, 0, 0, 0);
                rectTransform = m_TopBar.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 1);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);

                UnityEngine.GameObject LogCloseButton = new UnityEngine.GameObject("_X_CloseButton");
                m_UIGameObjects.Add("_X_CloseButton", LogCloseButton);
                LogCloseButton.transform.SetParent(m_TopBar.transform, false);
                LogCloseButton.AddComponent<UnityEngine.CanvasRenderer>();
                image = LogCloseButton.AddComponent<RawImage>();
                image.color = UnityEngine.Color.white;
                Button button = LogCloseButton.AddComponent<Button>();
                button.onClick.AddListener(Close);
                rectTransform = LogCloseButton.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(1, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                UnityEngine.GameObject ButtonText = new UnityEngine.GameObject("_X_CloseButtonText");
                m_UIGameObjects.Add("_X_CloseButtonText", ButtonText);
                ButtonText.transform.SetParent(LogCloseButton.transform, false);
                ButtonText.AddComponent<UnityEngine.CanvasRenderer>();
                text = ButtonText.AddComponent<Text>();
                text.alignment = UnityEngine.TextAnchor.MiddleCenter;
                text.alignByGeometry = true;
                text.color = UnityEngine.Color.black;
                text.text = "关闭";
                rectTransform = ButtonText.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                rectTransform.sizeDelta = new UnityEngine.Vector2(0, 0);

                UnityEngine.GameObject LogClearButton = new UnityEngine.GameObject("_X_ClearButton");
                m_UIGameObjects.Add("_X_ClearButton", LogClearButton);
                LogClearButton.transform.SetParent(m_TopBar.transform, false);
                LogClearButton.AddComponent<UnityEngine.CanvasRenderer>();
                image = LogClearButton.AddComponent<RawImage>();
                image.color = UnityEngine.Color.white;
                button = LogClearButton.AddComponent<Button>();
                button.onClick.AddListener(Clear);
                rectTransform = LogClearButton.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(1, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                ButtonText = new UnityEngine.GameObject("_X_ClearButtonText");
                m_UIGameObjects.Add("_X_ClearButtonText", ButtonText);
                ButtonText.transform.SetParent(LogClearButton.transform, false);
                ButtonText.AddComponent<UnityEngine.CanvasRenderer>();
                text = ButtonText.AddComponent<Text>();
                text.alignment = UnityEngine.TextAnchor.MiddleCenter;
                text.alignByGeometry = true;
                text.color = UnityEngine.Color.black;
                text.text = "清空";
                rectTransform = ButtonText.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                rectTransform.sizeDelta = new UnityEngine.Vector2(0, 0);

                UnityEngine.GameObject LogPauseButton = new UnityEngine.GameObject("_X_PauseButton");
                m_UIGameObjects.Add("_X_PauseButton", LogPauseButton);
                LogPauseButton.transform.SetParent(m_TopBar.transform, false);
                LogPauseButton.AddComponent<UnityEngine.CanvasRenderer>();
                PauseButtonImage = LogPauseButton.AddComponent<RawImage>();
                PauseButtonImage.color = UnityEngine.Color.white;
                button = LogPauseButton.AddComponent<Button>();
                button.onClick.AddListener(PauseButton);
                rectTransform = LogPauseButton.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(1, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                ButtonText = new UnityEngine.GameObject("_X_PauseButtonText");
                m_UIGameObjects.Add("_X_PauseButtonText", ButtonText);
                ButtonText.transform.SetParent(LogPauseButton.transform, false);
                ButtonText.AddComponent<UnityEngine.CanvasRenderer>();
                text = ButtonText.AddComponent<Text>();
                text.alignment = UnityEngine.TextAnchor.MiddleCenter;
                text.alignByGeometry = true;
                text.color = UnityEngine.Color.black;
                text.text = "暂停";
                rectTransform = ButtonText.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                rectTransform.sizeDelta = new UnityEngine.Vector2(0, 0);

                UnityEngine.GameObject LogStackButton = new UnityEngine.GameObject("_X_StackButton");
                m_UIGameObjects.Add("_X_StackButton", LogStackButton);
                LogStackButton.transform.SetParent(m_TopBar.transform, false);
                LogStackButton.AddComponent<UnityEngine.CanvasRenderer>();
                StackButtonImage = LogStackButton.AddComponent<RawImage>();
                StackButtonImage.color = new UnityEngine.Color(0.6f, 0.6f, 0.6f, 1);
                button = LogStackButton.AddComponent<Button>();
                button.onClick.AddListener(StackButton);
                rectTransform = LogStackButton.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(1, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                ButtonText = new UnityEngine.GameObject("_X_StackButtonText");
                m_UIGameObjects.Add("_X_StackButtonText", ButtonText);
                ButtonText.transform.SetParent(LogStackButton.transform, false);
                ButtonText.AddComponent<UnityEngine.CanvasRenderer>();
                text = ButtonText.AddComponent<Text>();
                text.alignment = UnityEngine.TextAnchor.MiddleCenter;
                text.alignByGeometry = true;
                text.color = UnityEngine.Color.black;
                text.text = "堆栈";
                rectTransform = ButtonText.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                rectTransform.sizeDelta = new UnityEngine.Vector2(0, 0);

                UnityEngine.GameObject LogDebugButton = new UnityEngine.GameObject("_X_DebugButton");
                m_UIGameObjects.Add("_X_DebugButton", LogDebugButton);
                LogDebugButton.transform.SetParent(m_TopBar.transform, false);
                LogDebugButton.AddComponent<UnityEngine.CanvasRenderer>();
                m_InfoButtonImage = LogDebugButton.AddComponent<RawImage>();
                m_InfoButtonImage.color = m_InfoColor;
                button = LogDebugButton.AddComponent<Button>();
                button.onClick.AddListener(DebugButton);
                rectTransform = LogDebugButton.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(0, 1);
                ButtonText = new UnityEngine.GameObject("_X_DebugButtonText");
                m_UIGameObjects.Add("_X_DebugButtonText", ButtonText);
                ButtonText.transform.SetParent(LogDebugButton.transform, false);
                ButtonText.AddComponent<UnityEngine.CanvasRenderer>();
                m_InfoButtonText = ButtonText.AddComponent<Text>();
                m_InfoButtonText.alignment = UnityEngine.TextAnchor.MiddleCenter;
                m_InfoButtonText.alignByGeometry = true;
                m_InfoButtonText.color = UnityEngine.Color.black;
                m_InfoButtonText.text = "信息[0]";
                rectTransform = ButtonText.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                rectTransform.sizeDelta = new UnityEngine.Vector2(0, 0);

                UnityEngine.GameObject LogEventButton = new UnityEngine.GameObject("_X_EventButton");
                m_UIGameObjects.Add("_X_EventButton", LogEventButton);
                LogEventButton.transform.SetParent(m_TopBar.transform, false);
                LogEventButton.AddComponent<UnityEngine.CanvasRenderer>();
                m_EventButtonImage = LogEventButton.AddComponent<RawImage>();
                m_EventButtonImage.color = m_EventColor;
                button = LogEventButton.AddComponent<Button>();
                button.onClick.AddListener(EventButton);
                rectTransform = LogEventButton.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(0, 1);
                ButtonText = new UnityEngine.GameObject("_X_EventButtonText");
                m_UIGameObjects.Add("_X_EventButtonText", ButtonText);
                ButtonText.transform.SetParent(LogEventButton.transform, false);
                ButtonText.AddComponent<UnityEngine.CanvasRenderer>();
                m_EventButtonText = ButtonText.AddComponent<Text>();
                m_EventButtonText.alignment = UnityEngine.TextAnchor.MiddleCenter;
                m_EventButtonText.alignByGeometry = true;
                m_EventButtonText.color = UnityEngine.Color.black;
                m_EventButtonText.text = "事件[0]";
                rectTransform = ButtonText.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                rectTransform.sizeDelta = new UnityEngine.Vector2(0, 0);

                UnityEngine.GameObject LogWarningButton = new UnityEngine.GameObject("_X_WarningButton");
                m_UIGameObjects.Add("_X_WarningButton", LogWarningButton);
                LogWarningButton.transform.SetParent(m_TopBar.transform, false);
                LogWarningButton.AddComponent<UnityEngine.CanvasRenderer>();
                m_WarningButtonImage = LogWarningButton.AddComponent<RawImage>();
                m_WarningButtonImage.color = m_WarningColor;
                button = LogWarningButton.AddComponent<Button>();
                button.onClick.AddListener(WarningButton);
                rectTransform = LogWarningButton.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(0, 1);
                ButtonText = new UnityEngine.GameObject("_X_WarningButtonText");
                m_UIGameObjects.Add("_X_WarningButtonText", ButtonText);
                ButtonText.transform.SetParent(LogWarningButton.transform, false);
                ButtonText.AddComponent<UnityEngine.CanvasRenderer>();
                m_WarningButtonText = ButtonText.AddComponent<Text>();
                m_WarningButtonText.alignment = UnityEngine.TextAnchor.MiddleCenter;
                m_WarningButtonText.alignByGeometry = true;
                m_WarningButtonText.color = UnityEngine.Color.black;
                m_WarningButtonText.text = "警告[0]";
                rectTransform = ButtonText.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                rectTransform.sizeDelta = new UnityEngine.Vector2(0, 0);

                UnityEngine.GameObject LogErrorButton = new UnityEngine.GameObject("_X_ErrorButton");
                m_UIGameObjects.Add("_X_ErrorButton", LogErrorButton);
                LogErrorButton.transform.SetParent(m_TopBar.transform, false);
                LogErrorButton.AddComponent<UnityEngine.CanvasRenderer>();
                m_ErrorButtonImage = LogErrorButton.AddComponent<RawImage>();
                m_ErrorButtonImage.color = m_ErrorColor;
                button = LogErrorButton.AddComponent<Button>();
                button.onClick.AddListener(ErrorButton);
                rectTransform = LogErrorButton.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(0, 1);
                ButtonText = new UnityEngine.GameObject("_X_ErrorButtonText");
                m_UIGameObjects.Add("_X_ErrorButtonText", ButtonText);
                ButtonText.transform.SetParent(LogErrorButton.transform, false);
                ButtonText.AddComponent<UnityEngine.CanvasRenderer>();
                m_ErrorButtonText = ButtonText.AddComponent<Text>();
                m_ErrorButtonText.alignment = UnityEngine.TextAnchor.MiddleCenter;
                m_ErrorButtonText.alignByGeometry = true;
                m_ErrorButtonText.color = UnityEngine.Color.black;
                m_ErrorButtonText.text = "错误[0]";
                rectTransform = ButtonText.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                rectTransform.sizeDelta = new UnityEngine.Vector2(0, 0);
            }

            //中间内容部分
            {
                m_LogBar = new UnityEngine.GameObject("_LogBar_");
                m_LogBar.transform.SetParent(m_WindowObject.transform, false);
                m_LogScrollRect = m_LogBar.AddComponent<ScrollRect>();
                m_LogScrollRect.movementType = ScrollRect.MovementType.Clamped;
                m_LogScrollRect.scrollSensitivity = 50;
                m_LogScrollRect.horizontal = false;
                m_LogScrollRect.vertical = true;
                m_LogBar.AddComponent<UnityEngine.CanvasRenderer>();
                image = m_LogBar.AddComponent<RawImage>();
                image.color = new UnityEngine.Color(0, 0, 0, 0);
                rectTransform = m_LogBar.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = UnityEngine.Vector2.zero;
                rectTransform.anchorMax = UnityEngine.Vector2.one;
                //rectTransform.offsetMin = new Vector2(fontSize / 2, fontSize * 2 + fontSize / 4);
                //rectTransform.offsetMax = new Vector2(-(fontSize / 2), -(fontSize * 2 + fontSize / 4));

                UnityEngine.GameObject LogViewport = new UnityEngine.GameObject("_X_Viewport");
                m_UIGameObjects.Add("_X_Viewport", LogViewport);
                LogViewport.transform.SetParent(m_LogBar.transform, false);
                Mask mask = LogViewport.AddComponent<Mask>();
                mask.showMaskGraphic = false;
                LogViewport.AddComponent<UnityEngine.CanvasRenderer>();
                image = LogViewport.AddComponent<RawImage>();
                rectTransform = LogViewport.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = UnityEngine.Vector2.zero;
                rectTransform.anchorMax = UnityEngine.Vector2.one;
                rectTransform.offsetMin = UnityEngine.Vector2.zero;
                rectTransform.offsetMax = UnityEngine.Vector2.zero;

                m_LogScrollRect.viewport = rectTransform;

                m_LogContent = new UnityEngine.GameObject("_X_Content");
                m_UIGameObjects.Add("_X_Content", m_LogContent);
                m_LogContent.transform.SetParent(LogViewport.transform, false);
                VerticalLayoutGroup verticalLayoutGroup = m_LogContent.AddComponent<VerticalLayoutGroup>();
                //verticalLayoutGroup.padding = new RectOffset(0, 0, fontSize / 2 - 2, fontSize / 2 + 2);
                verticalLayoutGroup.childControlWidth = true;
                verticalLayoutGroup.childControlHeight = true;
                verticalLayoutGroup.childForceExpandWidth = true;
                verticalLayoutGroup.childForceExpandHeight = false;
                //verticalLayoutGroup.spacing = fontSize;
                ContentSizeFitter contentSizeFitter = m_LogContent.AddComponent<ContentSizeFitter>();
                contentSizeFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
                contentSizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
                rectTransform = m_LogContent.transform as UnityEngine.RectTransform;
                rectTransform.pivot = new UnityEngine.Vector2(0, 1);
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 1);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                rectTransform.offsetMin = UnityEngine.Vector2.zero;
                rectTransform.offsetMax = UnityEngine.Vector2.zero;

                m_LogScrollRect.content = rectTransform;

                UnityEngine.GameObject LogScrollbarVertical = new UnityEngine.GameObject("_X_ScrollbarVertical");
                m_UIGameObjects.Add("_X_ScrollbarVertical", LogScrollbarVertical);
                LogScrollbarVertical.transform.SetParent(m_LogBar.transform, false);
                LogScrollbarVertical.AddComponent<UnityEngine.CanvasRenderer>();
                image = LogScrollbarVertical.AddComponent<RawImage>();
                image.color = new UnityEngine.Color(0.5f, 0.5f, 0.5f, 0.5f);
                Scrollbar scrollbar = LogScrollbarVertical.AddComponent<Scrollbar>();
                scrollbar.direction = Scrollbar.Direction.BottomToTop;
                rectTransform = LogScrollbarVertical.transform as UnityEngine.RectTransform;
                rectTransform.pivot = new UnityEngine.Vector2(1, 1);
                rectTransform.anchorMin = new UnityEngine.Vector2(1, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                //rectTransform.offsetMin = new Vector2(-(fontSize / 2), 0);
                //rectTransform.offsetMax = new Vector2(0, 0);

                m_LogScrollRect.verticalScrollbar = scrollbar;
                m_LogScrollRect.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport;

                UnityEngine.GameObject LogHandle = new UnityEngine.GameObject("_X_Handle");
                m_UIGameObjects.Add("_X_Handle", LogHandle);
                LogHandle.transform.SetParent(LogScrollbarVertical.transform, false);
                LogHandle.AddComponent<UnityEngine.CanvasRenderer>();
                image = LogHandle.AddComponent<RawImage>();
                image.color = UnityEngine.Color.white;
                rectTransform = LogHandle.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                rectTransform.offsetMin = new UnityEngine.Vector2(0, 0);
                rectTransform.offsetMax = new UnityEngine.Vector2(0, 0);

                scrollbar.targetGraphic = image;
                scrollbar.handleRect = rectTransform;
            }

            //下方输入部分
            {
                m_InputBar = new UnityEngine.GameObject("_InputBar_");
                m_InputBar.transform.SetParent(m_WindowObject.transform, false);
                m_InputBar.AddComponent<UnityEngine.CanvasRenderer>();
                image = m_InputBar.AddComponent<RawImage>();
                image.color = new UnityEngine.Color(0, 0, 0, 0);
                rectTransform = m_InputBar.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 0);

                UnityEngine.GameObject InputField = new UnityEngine.GameObject("_X_InputField");
                m_UIGameObjects.Add("_X_InputField", InputField);
                InputField.transform.SetParent(m_InputBar.transform, false);
                InputField.AddComponent<UnityEngine.CanvasRenderer>();
                image = InputField.AddComponent<RawImage>();
                image.color = UnityEngine.Color.white;
                m_LogInputField = InputField.AddComponent<InputField>();
                m_LogInputField.characterLimit = 256;
                if (UnityEngine.Application.platform == UnityEngine.RuntimePlatform.WindowsPlayer
                    || UnityEngine.Application.platform == UnityEngine.RuntimePlatform.WindowsEditor
                    || UnityEngine.Application.platform == UnityEngine.RuntimePlatform.OSXPlayer
                    || UnityEngine.Application.platform == UnityEngine.RuntimePlatform.OSXEditor)
                {
                    m_LogInputField.onEndEdit.AddListener(InputButton);
                }
                rectTransform = InputField.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                UnityEngine.GameObject Placeholder = new UnityEngine.GameObject("_X_Placeholder");
                m_UIGameObjects.Add("_X_Placeholder", Placeholder);
                Placeholder.transform.SetParent(InputField.transform, false);
                Placeholder.AddComponent<UnityEngine.CanvasRenderer>();
                text = Placeholder.AddComponent<Text>();
                text.color = new UnityEngine.Color(0.2f, 0.2f, 0.2f, 0.6f);
                text.alignment = UnityEngine.TextAnchor.MiddleLeft;
                text.fontStyle = UnityEngine.FontStyle.Italic;
                text.text = "输入调试指令";
                rectTransform = Placeholder.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                m_LogInputField.placeholder = text;
                UnityEngine.GameObject InputText = new UnityEngine.GameObject("_X_InputText");
                m_UIGameObjects.Add("_X_InputText", InputText);
                InputText.transform.SetParent(InputField.transform, false);
                InputText.AddComponent<UnityEngine.CanvasRenderer>();
                text = InputText.AddComponent<Text>();
                text.color = UnityEngine.Color.magenta;
                text.alignment = UnityEngine.TextAnchor.MiddleLeft;
                text.supportRichText = false;
                rectTransform = InputText.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                m_LogInputField.textComponent = text;

                UnityEngine.GameObject LogInputButton = new UnityEngine.GameObject("_X_InputButton");
                m_UIGameObjects.Add("_X_InputButton", LogInputButton);
                LogInputButton.transform.SetParent(m_InputBar.transform, false);
                LogInputButton.AddComponent<UnityEngine.CanvasRenderer>();
                image = LogInputButton.AddComponent<RawImage>();
                image.color = UnityEngine.Color.white;
                Button button = LogInputButton.AddComponent<Button>();
                button.onClick.AddListener(InputButton);
                rectTransform = LogInputButton.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(1, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                UnityEngine.GameObject ButtonText = new UnityEngine.GameObject("_X_InputButtonText");
                m_UIGameObjects.Add("_X_InputButtonText", ButtonText);
                ButtonText.transform.SetParent(LogInputButton.transform, false);
                ButtonText.AddComponent<UnityEngine.CanvasRenderer>();
                text = ButtonText.AddComponent<Text>();
                text.alignment = UnityEngine.TextAnchor.MiddleCenter;
                text.color = UnityEngine.Color.black;
                text.text = "输入";
                rectTransform = ButtonText.transform as UnityEngine.RectTransform;
                rectTransform.anchorMin = new UnityEngine.Vector2(0, 0);
                rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
                rectTransform.offsetMin = new UnityEngine.Vector2(0, 0);
                rectTransform.offsetMax = new UnityEngine.Vector2(0, 0);
            }

            //统一设置UGUI的Text组件所使用的字体
            Text[] texts = m_CanvasObject.GetComponentsInChildren<Text>(true);
            foreach (var item in texts)
            {
                item.font = m_Font;
                item.fontSize = m_FontSize;
            }
        }
        /// <summary>
        /// 设置字体
        /// </summary>
        /// <param name="font"></param>
        public void SetFont(UnityEngine.Font font)
        {
            m_Font = font;
            if (m_CanvasObject != null)
            {
                Text[] texts = m_CanvasObject.GetComponentsInChildren<Text>(true);
                foreach (var item in texts)
                {
                    item.font = m_Font;
                }
            }
        }
        /// <summary>
        /// 刷新界面大小
        /// </summary>
        public void RefreshWindowSize()
        {
            m_WindowsWidth = UnityEngine.Screen.width < UnityEngine.Screen.height ? UnityEngine.Screen.width : UnityEngine.Screen.height;
            m_WindowsHeight = (m_WindowsWidth * 2 / 3) & (0xFFFFFF - 1);

            UnityEngine.RectTransform rectTransform = m_WindowObject.GetComponent<UnityEngine.RectTransform>();
            rectTransform.sizeDelta = new UnityEngine.Vector2(m_WindowsWidth, m_WindowsHeight);

            //上方按钮部分
            rectTransform = m_TopBar.GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2(m_FontSize / 2, -(m_FontSize * 2));
            rectTransform.offsetMax = new UnityEngine.Vector2(-(m_FontSize / 2), -(m_FontSize / 2));

            rectTransform = m_UIGameObjects["_X_DebugButton"].GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2((m_FontSize * 5 + m_FontSize / 6) * 0, 0);
            rectTransform.offsetMax = new UnityEngine.Vector2((m_FontSize * 5 + m_FontSize / 6) * 0 + (m_FontSize * 5), 0);

            rectTransform = m_UIGameObjects["_X_EventButton"].GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2((m_FontSize * 5 + m_FontSize / 6) * 1, 0);
            rectTransform.offsetMax = new UnityEngine.Vector2((m_FontSize * 5 + m_FontSize / 6) * 1 + (m_FontSize * 5), 0);

            rectTransform = m_UIGameObjects["_X_WarningButton"].GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2((m_FontSize * 5 + m_FontSize / 6) * 2, 0);
            rectTransform.offsetMax = new UnityEngine.Vector2((m_FontSize * 5 + m_FontSize / 6) * 2 + (m_FontSize * 5), 0);

            rectTransform = m_UIGameObjects["_X_ErrorButton"].GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2((m_FontSize * 5 + m_FontSize / 6) * 3, 0);
            rectTransform.offsetMax = new UnityEngine.Vector2((m_FontSize * 5 + m_FontSize / 6) * 3 + (m_FontSize * 5), 0);

            rectTransform = m_UIGameObjects["_X_CloseButton"].GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2(-((m_FontSize * 4 + m_FontSize / 6) * 0 + (m_FontSize * 4)), 0);
            rectTransform.offsetMax = new UnityEngine.Vector2(-(m_FontSize * 4 + m_FontSize / 6) * 0, 0);

            rectTransform = m_UIGameObjects["_X_ClearButton"].GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2(-((m_FontSize * 4 + m_FontSize / 6) * 1 + (m_FontSize * 4)), 0);
            rectTransform.offsetMax = new UnityEngine.Vector2(-(m_FontSize * 4 + m_FontSize / 6) * 1, 0);

            rectTransform = m_UIGameObjects["_X_PauseButton"].GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2(-((m_FontSize * 4 + m_FontSize / 6) * 2 + (m_FontSize * 4)), 0);
            rectTransform.offsetMax = new UnityEngine.Vector2(-(m_FontSize * 4 + m_FontSize / 6) * 2, 0);

            rectTransform = m_UIGameObjects["_X_StackButton"].GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2(-((m_FontSize * 4 + m_FontSize / 6) * 3 + (m_FontSize * 4)), 0);
            rectTransform.offsetMax = new UnityEngine.Vector2(-(m_FontSize * 4 + m_FontSize / 6) * 3, 0);

            //中间内容部分
            rectTransform = m_LogBar.GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2(m_FontSize / 2, m_FontSize * 2 + m_FontSize / 4);
            rectTransform.offsetMax = new UnityEngine.Vector2(-(m_FontSize / 2), -(m_FontSize * 2 + m_FontSize / 4));

            rectTransform = m_UIGameObjects["_X_ScrollbarVertical"].GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2(-(m_FontSize / 2), 0);
            rectTransform.offsetMax = new UnityEngine.Vector2(0, 0);

            VerticalLayoutGroup verticalLayoutGroup = m_UIGameObjects["_X_Content"].GetComponent<VerticalLayoutGroup>();
            verticalLayoutGroup.padding = new UnityEngine.RectOffset(0, 0, m_FontSize / 2 - 2, m_FontSize / 2 + 2);
            verticalLayoutGroup.spacing = m_FontSize;

            //下方输入部分
            rectTransform = m_InputBar.GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2(m_FontSize / 2, m_FontSize / 2);
            rectTransform.offsetMax = new UnityEngine.Vector2(-(m_FontSize / 2), m_FontSize * 2);

            rectTransform = m_UIGameObjects["_X_InputField"].GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2(0, 0);
            rectTransform.offsetMax = new UnityEngine.Vector2(-((m_FontSize * 4) + (m_FontSize / 6)), 0);

            rectTransform = m_UIGameObjects["_X_Placeholder"].GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2(m_FontSize / 4, 0);
            rectTransform.offsetMax = new UnityEngine.Vector2(-(m_FontSize / 4), 0);

            rectTransform = m_UIGameObjects["_X_InputText"].GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2(m_FontSize / 4, 0);
            rectTransform.offsetMax = new UnityEngine.Vector2(-(m_FontSize / 4), 0);

            rectTransform = m_UIGameObjects["_X_InputButton"].GetComponent<UnityEngine.RectTransform>();
            rectTransform.offsetMin = new UnityEngine.Vector2(-(m_FontSize * 4), 0);
            rectTransform.offsetMax = new UnityEngine.Vector2(0, 0);
        }

        // 打开控制台界面
        public void Open()
        {
            CreateWindow();
            RefreshWindowSize();
            m_CanvasObject.SetActive(true);
        }
        // 关闭控制台界面
        public void Close()
        {
            m_CanvasObject.SetActive(false);
        }
        // 清空
        public void Clear()
        {
            if (m_CanvasObject == null)
            {
                return;
            }
            foreach (var item in m_ShowItems)
            {
                UnityEngine.Object.Destroy(item.gameObject);
            }
            m_ShowItems.Clear();
            m_BufferItems.Clear();
            m_InfoCount = 0;
            m_WarningCount = 0;
            m_ErrorCount = 0;
            m_EventCount = 0;
            m_InfoButtonText.text = "信息[0]";
            m_WarningButtonText.text = "警告[0]";
            m_ErrorButtonText.text = "错误[0]";
            m_EventButtonText.text = "事件[0]";
        }
        // 添加记录
        public void Add(string content, DateTime time, string stack, UnityEngine.LogType type)
        {
            lock (m_BufferItems)
            {
                m_BufferItems.Add(new ItemData { content = content, time = time, stack = stack, type = type, });
                if (m_BufferItems.Count > m_MaxCount)
                {
                    m_BufferItems.RemoveAt(0);
                }
            }
        }
        private void Update()
        {
            if (isPause) return;
            if (m_BufferItems.Count == 0) return;

            lock (m_BufferItems)
            {
                if (m_BufferItems.Count > 10)
                {
                    for (int i = 0; i < 10; i++)
                    {
                        Add_Internal(m_BufferItems[i]);
                    }
                    m_BufferItems.RemoveRange(0, 10);
                }
                else
                {
                    foreach (var item in m_BufferItems)
                    {
                        Add_Internal(item);
                    }
                    m_BufferItems.Clear();
                }
            }

            m_InfoButtonText.text = "信息[" + m_InfoCount + "]";
            m_WarningButtonText.text = "警告[" + m_WarningCount + "]";
            m_ErrorButtonText.text = "错误[" + m_ErrorCount + "]";
            m_EventButtonText.text = "事件[" + m_EventCount + "]";

            LayoutRebuilder.ForceRebuildLayoutImmediate(m_LogContent.GetComponent<UnityEngine.RectTransform>());
            m_LogScrollRect.normalizedPosition = UnityEngine.Vector2.zero;
        }
        // 内部添加记录
        private void Add_Internal(ItemData itemData)
        {
            //最大支持显示1万5千文字
            if (itemData.content.Length > 15000)
            {
                itemData.content = itemData.content.Substring(0, 15000) + "<消息被截断>";
            }

            UnityEngine.GameObject go = new UnityEngine.GameObject("_X_Item");
            go.transform.SetParent(m_LogContent.transform, false);
            itemData.gameObject = go;
            m_ShowItems.Add(itemData);

            Text text = go.AddComponent<Text>();
            text.font = m_Font;
            text.alignment = UnityEngine.TextAnchor.MiddleLeft;
            text.fontSize = m_FontSize;
            text.text = isShowStack ? "[" + itemData.time.ToString("T") + "] " + itemData.content + "\n" + itemData.stack : "[" + itemData.time.ToString("T") + "] " + itemData.content;
            switch (itemData.type)
            {
                case UnityEngine.LogType.Log:
                    {
                        text.color = m_InfoColor;
                        m_InfoCount++;
                        if (!m_OpenInfo)
                        {
                            go.SetActive(false);
                        }
                    }
                    break;
                case UnityEngine.LogType.Warning:
                    {
                        text.color = m_WarningColor;
                        m_WarningCount++;
                        if (!m_OpenWarning)
                        {
                            go.SetActive(false);
                        }
                    }
                    break;
                case UnityEngine.LogType.Error:
                case UnityEngine.LogType.Exception:
                    {
                        text.color = m_ErrorColor;
                        m_ErrorCount++;
                        if (!m_OpenError)
                        {
                            go.SetActive(false);
                        }
                    }
                    break;
                default:
                    {
                        text.color = m_EventColor;
                        m_EventCount++;
                        if (!m_OpenEvent)
                        {
                            go.SetActive(false);
                        }
                    }
                    break;
            }

            UnityEngine.GameObject gob = new UnityEngine.GameObject("_X_ItemLine");
            gob.transform.SetParent(go.transform, false);
            gob.AddComponent<UnityEngine.CanvasRenderer>();
            RawImage image = gob.AddComponent<RawImage>();
            image.color = m_SeparateLineColor;
            UnityEngine.RectTransform rectTransform = gob.transform as UnityEngine.RectTransform;
            rectTransform.anchorMin = new UnityEngine.Vector2(0, 1);
            rectTransform.anchorMax = new UnityEngine.Vector2(1, 1);
            rectTransform.offsetMin = new UnityEngine.Vector2(0, m_FontSize / 2 - 1);
            rectTransform.offsetMax = new UnityEngine.Vector2(0, m_FontSize / 2);

            if (m_ShowItems.Count > m_MaxCount)
            {
                itemData = m_ShowItems[0];
                m_ShowItems.RemoveAt(0);
                UnityEngine.Object.Destroy(itemData.gameObject);
                itemData.gameObject = null;
                switch (itemData.type)
                {
                    case UnityEngine.LogType.Log:
                        m_InfoCount--;
                        break;
                    case UnityEngine.LogType.Warning:
                        m_WarningCount--;
                        break;
                    case UnityEngine.LogType.Error:
                    case UnityEngine.LogType.Exception:
                        m_ErrorCount--;
                        break;
                    default:
                        m_EventCount--;
                        break;
                }
            }
        }
        private void RefreshItemSize()
        {
            LayoutRebuilder.ForceRebuildLayoutImmediate(m_LogContent.GetComponent<UnityEngine.RectTransform>());
            m_LogScrollRect.normalizedPosition = UnityEngine.Vector2.zero;
        }
        private void DebugButton()
        {
            m_OpenInfo = !m_OpenInfo;
            if (m_OpenInfo)
            {
                m_InfoButtonImage.color = m_InfoColor;
                foreach (var item in m_ShowItems)
                {
                    if (item.type == UnityEngine.LogType.Log)
                    {
                        item.gameObject.SetActive(true);
                    }
                }
            }
            else
            {
                m_InfoButtonImage.color = new UnityEngine.Color(m_InfoColor.r * 0.6f, m_InfoColor.g * 0.6f, m_InfoColor.b * 0.6f, 1);
                foreach (var item in m_ShowItems)
                {
                    if (item.type == UnityEngine.LogType.Log)
                    {
                        item.gameObject.SetActive(false);
                    }
                }
            }
            RefreshItemSize();
        }
        private void WarningButton()
        {
            m_OpenWarning = !m_OpenWarning;
            if (m_OpenWarning)
            {
                m_WarningButtonImage.color = m_WarningColor;
                foreach (var item in m_ShowItems)
                {
                    if (item.type == UnityEngine.LogType.Warning)
                    {
                        item.gameObject.SetActive(true);
                    }
                }
            }
            else
            {
                m_WarningButtonImage.color = new UnityEngine.Color(m_WarningColor.r * 0.6f, m_WarningColor.g * 0.6f, m_WarningColor.b * 0.6f, 1);
                foreach (var item in m_ShowItems)
                {
                    if (item.type == UnityEngine.LogType.Warning)
                    {
                        item.gameObject.SetActive(false);
                    }
                }
            }
            RefreshItemSize();
        }
        private void ErrorButton()
        {
            m_OpenError = !m_OpenError;
            if (m_OpenError)
            {
                m_ErrorButtonImage.color = m_ErrorColor;
                foreach (var item in m_ShowItems)
                {
                    if (item.type == UnityEngine.LogType.Error || item.type == UnityEngine.LogType.Exception)
                    {
                        item.gameObject.SetActive(true);
                    }
                }
            }
            else
            {
                m_ErrorButtonImage.color = new UnityEngine.Color(m_ErrorColor.r * 0.6f, m_ErrorColor.g * 0.6f, m_ErrorColor.b * 0.6f, 1);
                foreach (var item in m_ShowItems)
                {
                    if (item.type == UnityEngine.LogType.Error || item.type == UnityEngine.LogType.Exception)
                    {
                        item.gameObject.SetActive(false);
                    }
                }
            }
            RefreshItemSize();
        }
        private void EventButton()
        {
            m_OpenEvent = !m_OpenEvent;
            if (m_OpenEvent)
            {
                m_EventButtonImage.color = m_EventColor;
                foreach (var item in m_ShowItems)
                {
                    if (item.type == UnityEngine.LogType.Assert)
                    {
                        item.gameObject.SetActive(true);
                    }
                }
            }
            else
            {
                m_EventButtonImage.color = new UnityEngine.Color(m_EventColor.r * 0.6f, m_EventColor.g * 0.6f, m_EventColor.b * 0.6f, 1);
                foreach (var item in m_ShowItems)
                {
                    if (item.type == UnityEngine.LogType.Assert)
                    {
                        item.gameObject.SetActive(false);
                    }
                }
            }
            RefreshItemSize();
        }
        private void PauseButton()
        {
            isPause = !isPause;
            if (isPause)
            {
                PauseButtonImage.color = new UnityEngine.Color(0.6f, 0.6f, 0.6f, 1);
            }
            else
            {
                PauseButtonImage.color = UnityEngine.Color.white;
            }
        }
        private void StackButton()
        {
            isShowStack = !isShowStack;
            if (isShowStack)
            {
                StackButtonImage.color = UnityEngine.Color.white;
                foreach (var item in m_ShowItems)
                {
                    item.gameObject.GetComponentInChildren<Text>().text = "[" + item.time.ToString("T") + "] " + item.content + "\n" + item.stack;
                }
            }
            else
            {
                StackButtonImage.color = new UnityEngine.Color(0.6f, 0.6f, 0.6f, 1);
                foreach (var item in m_ShowItems)
                {
                    item.gameObject.GetComponentInChildren<Text>().text = "[" + item.time.ToString("T") + "] " + item.content;
                }
            }
            LayoutRebuilder.ForceRebuildLayoutImmediate(m_LogContent.GetComponent<UnityEngine.RectTransform>());
            m_LogScrollRect.normalizedPosition = UnityEngine.Vector2.zero;
        }
        private void InputButton()
        {
            if (m_LogInputField.text != null && m_LogInputField.text.Length > 0)
            {
                OnInput?.Invoke(m_LogInputField.text);
                m_LastInputText = m_LogInputField.text;
                m_LogInputField.text = "";
            }
            else
            {
                m_LogInputField.text = m_LastInputText;
            }
        }
        private void InputButton(string str)
        {
            if (m_LogInputField.text != null && m_LogInputField.text.Length > 0)
            {
                OnInput?.Invoke(m_LogInputField.text);
                m_LastInputText = m_LogInputField.text;
                m_LogInputField.text = "";
            }
            else
            {
                m_LogInputField.text = m_LastInputText;
            }
        }
    }
}